/*
 * mdVisualizacion.cpp
 *
 *  Created on: 09-may-2009
 *      Author: Luis
 */

#include "mdVisualizacion.h"
#define	PI 3.141592654
#include <math.h>

void DibujarEjes(void){
	glBegin(GL_LINES);
	//eje X
	glVertex3f(-1.5, 0.0, 0.0);
	glVertex3f(1.5, 0.0, 0.0);
	//eje Y
	glVertex3f(0.0, -1.5, 0.0);
	glVertex3f(0.0, 1.5, 0.0);
	//eje Z
	glVertex3f(0.0, 0.0, -1.5);
	glVertex3f(0.0, 0.0, 1.5);
	glEnd();
}

void DibujarEsfera(void){
	float x, y, z;
	float r = 1.0, rho, theta;
	int i, j;

	glBegin(GL_POINTS);
	rho = 0.0;
	x = (float) (r * sin(rho) * cos(theta));
	y = (float) (r * sin(rho) * sin(theta));
	z = (float) (r * cos(rho));
	glVertex3f(x, y, z);
	for (i = 1; i < 100; i++){
		rho = PI * i / 100;
		for (j = 0; j < 50; j++){
			theta = 2*PI * j / 50;
			x = (float) (r * sin(rho) * cos(theta));
			y = (float) (r * sin(rho) * sin(theta));
			z = (float) (r * cos(rho));
			glVertex3f(x, y, z);
		}
	}
	rho = PI;
	x = (float) (r * sin(rho) * cos(theta));
	y = (float) (r * sin(rho) * sin(theta));
	z = (float) (r * cos(rho));
	glVertex3f(x, y, z);
	glEnd();
}

mdVisualizacion::mdVisualizacion(QWidget *parent) :
	QGLWidget(parent){
	// TODO Auto-generated constructor stub
	scale = 0.8;
	rotarx = 0.0;
	rotary = 0.0;
	rotarz = 0.0;
	center[0] = 1.0;
	center[1] = 1.0;
	center[2] = 1.0;
}

mdVisualizacion::~mdVisualizacion(){
	// TODO Auto-generated destructor stub
}

void mdVisualizacion::paintGL(){
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glRotatef(rotarx, 1.0, 0.0, 0.0);
	glRotatef(rotary, 0.0, 1.0, 0.0);
	glRotatef(rotarz, 0.0, 0.0, 1.0);
	glTranslatef(-center[0], -center[1], -center[2]);

	// Clear window
	glClearColor(0.04, 0.04, 0.04, 0.0);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Set material
	GLfloat material[] = { 0.5, 1.0, 0.5, 0.6 };
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material);

	glPolygonMode(GL_FRONT, GL_FILL);
	glPolygonMode(GL_BACK, GL_FILL);

	// Set lights
	static GLfloat light0_position[] = { 3.0, 4.0, 5.0, 0.0 };
	glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
	static GLfloat light1_position[] = { -3.0, -2.0, -3.0, 0.0 };
	glLightfv(GL_LIGHT1, GL_POSITION, light1_position);

	// Set Transparency
	//glEnable(GL_BLEND);
	//glBlendFunc(GL_DST_ALPHA, GL_ZERO);

	// Renderizado de Puntos!
	glPushMatrix();
	glPointSize(2);
	double t;

	for (double ii = 0.0; ii <= 2.0; ii += 0.08){
		for (double jj = 0.0; jj <= 2.0; jj += 0.08){
			for (double kk = 0.0; kk <= 2.0; kk += 0.08){
				t = pow(ii,2) * jj * kk;
				//glColor3f(1 - (ii*jj*kk/8.0), 1.0 - (ii*jj*kk/16.0), (ii*jj*kk/8.0));
				material[0] = t / 8.0;
				material[2] = 1 - (t / 8.0);
				if (t <= 8){
					material[1] = 0.0 + t / 16.0;
					//material[0] += material[1];
					material[2] -= material[1];
				}
				if (t <= 6){
					material[1] = 0.5 + t / 16.0;
					material[0] += material[1];
					material[2] -= material[1];
				}
				if (t <= 4){
					material[1] = 0.5 + t / 16.0;
					material[0] -= material[1];
					material[2] += material[1];
				}
				if (t <= 2){
					material[1] = 0.0 + t / 16.0;
					material[0] -= material[1];
					//material[2] += material[1];
				}

				glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, material);
				glBegin(GL_POINTS);
				glVertex3f(ii, jj, kk);
				glEnd();
			}
		}
	}
	glPopMatrix();

	/*
	 glBegin(GL_POLYGON);
	 glNormal3f(0.0,1.0,0.0);
	 glVertex3f(-0.9, 0.0, 0.0);
	 glVertex3f(0.5, 0.0, 0.0);
	 glVertex3f(0.5, 0.0, 0.5);
	 glVertex3f(-0.9, 0.0, 0.5);
	 glEnd();
	 */
}

void mdVisualizacion::initializeGL(){

	static GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
	static GLfloat light0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
	glEnable(GL_LIGHT0);
	static GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
	glEnable(GL_LIGHT1);
	glEnable(GL_NORMALIZE);
	glEnable(GL_LIGHTING);
	glShadeModel(GL_SMOOTH);

	// Initialize graphics modes
	glEnable(GL_DEPTH_TEST);

}

void mdVisualizacion::resizeGL(int w, int h){
	if (!h)
		return;
	glPushMatrix();
	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (GLfloat) w / (GLfloat) h, 1.0, 100.0);
	gluLookAt(0.0, 0.0, -8.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glPopMatrix();
}

void mdVisualizacion::keyPressEvent(QKeyEvent *event){
	if (event->key() == Qt::Key_Plus){
		scale += scale*0.1;
	}
	if (event->key() == Qt::Key_Minus){
		scale -= scale*0.1;
	}
	printf("Escala = %.3f\n", scale);
	updateGL();
}

void mdVisualizacion::mousePressEvent(QMouseEvent* e){
	xant = e->x();
	yant = windowHeight - e->y();
}

void mdVisualizacion::mouseMoveEvent(QMouseEvent *e){
	if (e->buttons() & Qt::RightButton){
		int x = e->x();
		int y = windowHeight - e->y();
		rotarx += -0.5 * (y - yant);
		rotarz += 0.5 * (x - xant);

		xant = e->x();
		yant = windowHeight - e->y();
		updateGL();
	}
}

void mdVisualizacion::wheelEvent(QWheelEvent *e){
	printf("Wheel event!\n");
    (e->delta() > 0) ? scale += scale*0.1 : scale -= scale*0.1;
    updateGL();
}
